
/******************************************************************************
* @file      : hal_timer.c
* @version   : 1.0
* @date      : 2021.4.2
* @brief     : TIMER Extended HAL module driver  
* @history   :	
*   2021.4.2        xwl     create
*   2023.2.8        lwq     Modify the file header and function header comment format                                 
******************************************************************************/
#include "hal.h"  


/******************************************************************************
*@brief:  configure deadtime parameter.
*@param:  htimer: pointer to a TIM_HandleTypeDef structure that contains
*         the configuration information for the specified TIMER module.
*@param:  sBreakDeadTimeConfig: break and deadtime configuration.    
*@return: None
******************************************************************************/ 
void HAL_TIMEx_ConfigBreakDeadTime(TIM_HandleTypeDef *htim, TIM_BreakDeadTimeConfigTypeDef * sBreakDeadTimeConfig)
{
    /* Keep this variable initialized to 0 as it is used to configure BDTR register */
    uint32_t break_deadtime_reg = 0U;

    /* Set the BDTR bits */
    MODIFY_REG(break_deadtime_reg, TIM_BDTR_DTG,  sBreakDeadTimeConfig->DeadTime);
    MODIFY_REG(break_deadtime_reg, TIM_BDTR_LOCK, sBreakDeadTimeConfig->LockLevel);
    MODIFY_REG(break_deadtime_reg, TIM_BDTR_OSSI, sBreakDeadTimeConfig->OffStateIDLEMode);
    MODIFY_REG(break_deadtime_reg, TIM_BDTR_OSSR, sBreakDeadTimeConfig->OffStateRunMode);
    MODIFY_REG(break_deadtime_reg, TIM_BDTR_BKE, sBreakDeadTimeConfig->BreakState);
    MODIFY_REG(break_deadtime_reg, TIM_BDTR_BKP, sBreakDeadTimeConfig->BreakPolarity);
    MODIFY_REG(break_deadtime_reg, TIM_BDTR_AOE, sBreakDeadTimeConfig->AutomaticOutput);
    MODIFY_REG(break_deadtime_reg, TIM_BDTR_BKF, (sBreakDeadTimeConfig->BreakFilter << TIM_BDTR_BKF_Pos));

    /* Set TIMx_BDTR */
    htim->Instance->BDTR = break_deadtime_reg;  

}
  
/******************************************************************************
*@brief:  Configures the break input source.
*@param:  htimer: pointer to a TIM_HandleTypeDef structure that contains
*         the configuration information for the specified TIMER module.
*@param:  BreakInput: TIM_BREAKINPUT_BRK 
*@param:  sBreakInputConfig: Break input source configuration.    
*@return: HAL_ERROR:error, HAL_OK:OK
******************************************************************************/ 
HAL_StatusTypeDef HAL_TIMEx_ConfigBreakInput(TIM_HandleTypeDef *htim, uint32_t BreakInput, TIMEx_BreakInputConfigTypeDef *sBreakInputConfig)
{
    uint32_t tmporx;
    uint32_t bkin_enable_mask;
    uint32_t bkin_polarity_mask;
    uint32_t bkin_enable_bitpos;
    uint32_t bkin_polarity_bitpos;   

    switch(sBreakInputConfig->Source)
    {
        case TIM_BREAKINPUTSOURCE_BKIN:
        {
            bkin_enable_mask = TIM_AF1_BKINE;
            bkin_enable_bitpos = TIM_AF1_BKINE_Pos;
            bkin_polarity_mask = TIM_AF1_BKINP;
            bkin_polarity_bitpos = TIM_AF1_BKINP_Pos;
            break;
        }
#ifdef HAL_COMP_MODULE_ENABLED  
        case TIM_BREAKINPUTSOURCE_COMP1:
        {
            bkin_enable_mask = TIM_AF1_BKCMP1E;
            bkin_enable_bitpos = TIM_AF1_BKCMP1E_Pos;
            bkin_polarity_mask = TIM_AF1_BKCMP1P;
            bkin_polarity_bitpos = TIM_AF1_BKCMP1P_Pos;
            break;
        }
        case TIM_BREAKINPUTSOURCE_COMP2:
        {
            bkin_enable_mask = TIM_AF1_BKCMP2E;
            bkin_enable_bitpos = TIM_AF1_BKCMP2E_Pos;
            bkin_polarity_mask = TIM_AF1_BKCMP2P;
            bkin_polarity_bitpos = TIM_AF1_BKCMP2P_Pos;
            break;
        }
        case TIM_BREAKINPUTSOURCE_COMP3:
        {
            bkin_enable_mask = TIM_AF1_BKCMP3E;
            bkin_enable_bitpos = TIM_AF1_BKCMP3E_Pos;
            bkin_polarity_mask = TIM_AF1_BKCMP3P;
            bkin_polarity_bitpos = TIM_AF1_BKCMP3P_Pos;
            break;
        }
        case TIM_BREAKINPUTSOURCE_COMP4:
        {
            bkin_enable_mask = TIM_AF1_BKCMP4E;
            bkin_enable_bitpos = TIM_AF1_BKCMP4E_Pos;
            bkin_polarity_mask = TIM_AF1_BKCMP4P;
            bkin_polarity_bitpos = TIM_AF1_BKCMP4P_Pos;
            break;
        }
#endif /* COMP1 && COMP2 && COMP3 && COMP4 */

        default:
        {
            bkin_enable_mask = 0U;
            bkin_enable_bitpos = 0U;
            bkin_polarity_mask = 0U;
            bkin_polarity_bitpos = 0U;
            break;
        }
    }

//    switch(BreakInput)
//    {
//        case TIM_BREAKINPUT_BRK:
//        {
    /* Get the TIMx_AF1 register value */
    tmporx = htim->Instance->AF1;

    /* Enable the break input */
    tmporx &= ~bkin_enable_mask;
    tmporx |= (sBreakInputConfig->Enable << bkin_enable_bitpos) & bkin_enable_mask;

    /* Set the break input polarity */
    tmporx &= ~bkin_polarity_mask;
    tmporx |= (sBreakInputConfig->Polarity << bkin_polarity_bitpos) & bkin_polarity_mask;

    /* Set TIMx_AF1 */
    htim->Instance->AF1 = tmporx;        
//        break;
//        }

//    default:
//    break;
//    }

    return HAL_OK;  
}   

/******************************************************************************
*@brief:  Configure the TIM commutation event sequence. This function is 
*         mandatory to use the commutation event in order to update the 
*         configuration at each commutation detection on the TRGI input of the Timer.
*@param:  htimer: pointer to a TIM_HandleTypeDef structure that contains
*         the configuration information for the specified TIMER module.
*@param:  InputTrigger: TIM_TS_ITR0, TIM_TS_ITR1...  
*@param:  CommutationSource: TIM_COMMUTATION_TRGI, TIM_COMMUTATION_SOFTWARE .    
*@return: None
******************************************************************************/ 
void HAL_TIMEx_ConfigCommutEvent(TIM_HandleTypeDef *htim, uint32_t  InputTrigger, uint32_t  CommutationSource)
{
    if ((InputTrigger == TIM_TS_ITR0) || \
        (InputTrigger == TIM_TS_ITR1) || \
        (InputTrigger == TIM_TS_ITR2) || \
        (InputTrigger == TIM_TS_ITR3) || \
        (InputTrigger == TIM_TS_ITR4) || \
        (InputTrigger == TIM_TS_ITR5) || \
        (InputTrigger == TIM_TS_ITR6) || \
        (InputTrigger == TIM_TS_ITR7) || \
        (InputTrigger == TIM_TS_ITR8) || \
        (InputTrigger == TIM_TS_ITR9) || \
        (InputTrigger == TIM_TS_ITR10))
    {
        /* Select the Input trigger */
        htim->Instance->SMCR &= (~TIM_SMCR_TS_Msk);
        htim->Instance->SMCR |= InputTrigger;
    }

    /* Select the Capture Compare preload feature */
    htim->Instance->CR2 |= TIM_CR2_CCPC;
    /* Select the Commutation event source */
    htim->Instance->CR2 &= ~TIM_CR2_CCUS;
    htim->Instance->CR2 |= CommutationSource;

    /* Disable Commutation Interrupt */
    HAL_TIM_DISABLE_IT(htim, TIM_IT_COM);

    /* Disable Commutation DMA request */
    HAL_TIM_DISABLE_DMA(htim, TIM_DMA_COM);

}

/******************************************************************************
*@brief:  Configure the TIM commutation event sequence. This function is 
*         mandatory to use the commutation event in order to update the 
*         configuration at each commutation detection on the TRGI input of the Timer.
*@param:  htimer: pointer to a TIM_HandleTypeDef structure that contains
*         the configuration information for the specified TIMER module.
*@param:  TISelection: specifies the timer input source.
*@param:  Channel: specifies the TIM Channel.    
*@return: HAL_ERROR:error, HAL_OK:OK
******************************************************************************/ 
HAL_StatusTypeDef  HAL_TIMEx_TISelection(TIM_HandleTypeDef *htim, uint32_t TISelection, uint32_t Channel)
{
    HAL_StatusTypeDef status = HAL_OK;

    switch (Channel)
    {
        case TIM_CHANNEL_1:
            MODIFY_REG(htim->Instance->TISEL, TIM_TISEL_TI1SEL, TISelection);
        break;
        case TIM_CHANNEL_2:
            MODIFY_REG(htim->Instance->TISEL, TIM_TISEL_TI2SEL, TISelection);
        break;
        case TIM_CHANNEL_3:
            MODIFY_REG(htim->Instance->TISEL, TIM_TISEL_TI3SEL, TISelection);
        break;
        case TIM_CHANNEL_4:
            MODIFY_REG(htim->Instance->TISEL, TIM_TISEL_TI4SEL, TISelection);
        break;
        default:
            status = HAL_ERROR;
        break;
    }

    return status;
}

/******************************************************************************
*@brief:  Initializes Encoder MSP.
*@param:  htimer: pointer to a TIM_HandleTypeDef structure that contains
*         the configuration information for the specified TIMER module.   
*@return: None
******************************************************************************/ 
__WEAK void HAL_TIMEx_Encoder_MspInit(TIM_HandleTypeDef *htim)
{
    /* Prevent unused argument(s) compilation warning */
    UNUSED(htim);

    /* NOTE : This function could be implemented in the user file
    */
}

/******************************************************************************
*@brief:  DeInitializes Encoder MSP.
*@param:  htimer: pointer to a TIM_HandleTypeDef structure that contains
*         the configuration information for the specified TIMER module.   
*@return: None
******************************************************************************/ 
__WEAK void HAL_TIMEx_Encoder_MspDeInit(TIM_HandleTypeDef *htim)
{
    /* Prevent unused argument(s) compilation warning */
    UNUSED(htim);

    /* NOTE : This function could be implemented in the user file
    */
}

/******************************************************************************
*@brief:  Configure the TIM encoder mode.
*@param:  htimer: pointer to a TIM_HandleTypeDef structure that contains
*         the configuration information for the specified TIMER module.
*@param:  EncoderMode: TIM encoder mode, only can be: TIM_SLAVE_MODE_ENC1, 
*         TIM_SLAVE_MODE_ENC2, TIM_SLAVE_MODE_ENC3;   
*@return: HAL_ERROR:error, HAL_OK:OK
******************************************************************************/
HAL_StatusTypeDef HAL_TIMEx_Encoder_Init(TIM_HandleTypeDef *htim, uint8_t EncoderMode)
{    
    assert_param(IS_TIM_ENCODER_INSTANCE(htim->Instance));

    /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */
    HAL_TIMEx_Encoder_MspInit(htim);

    /* Configure the encoder mode */
    htim->Instance->SMCR = (htim->Instance->SMCR & ~(BIT0|BIT1|BIT2) | EncoderMode);

    return HAL_OK;
}

/******************************************************************************
*@brief:  Enable the TIM encoder.
*@param:  htimer: pointer to a TIM_HandleTypeDef structure that contains
*         the configuration information for the specified TIMER module.
*@return: HAL_ERROR:error, HAL_OK:OK
******************************************************************************/
HAL_StatusTypeDef HAL_TIMEx_Encoder_Enable(TIM_HandleTypeDef *htim)
{    
    assert_param(IS_TIM_ENCODER_INSTANCE(htim->Instance));

    /* Enable the TIM */
    htim->Instance->CR1 |= BIT0;

    return HAL_OK;
}

/******************************************************************************
*@brief:  Get TIM encoder value.
*@param:  htim: pointer to a TIM_HandleTypeDef structure that contains
*         the configuration information for the specified TIMER module.  
*@return: Encoder value   
******************************************************************************/ 
uint32_t HAL_TIMEx_Encoder_GetValue(TIM_HandleTypeDef *htim)
{      
    return ((uint32_t)htim->Instance->CNT);
}

